/*file chiron src/test/base/dict.js */
/*preamble

    Copyright (c) 2002-2008 Kris Kowal <http://cixar.com/~kris.kowal>
    MIT License
    
    The license terms are stated in full in <license.rst> and at the end
    of all source files.

*/

include('base');
include('test');

assert(eq([1], [1]), 'arrays are safe for comparison');
assert(eq([1], Set([1])), 'arrays are safe for comparison with sets');
assert(eq([1], List([1])), 'arrays are safe for comparison with lists');
assert(eq(Set([1]), [1]), 'sets are safe to compare with arrays');
assert(eq(List([1]),[1]), 'lists are safe to compare with sets');
assert(!eq(1, '1'), 'type safe eq for type-safe hashing');

assert(has({'a': 10}, 'a'), 'object has member');
assert(dict({'a': 10}).has('a'), 'dict has member');

var key = Base();
var value = 10;
var items = dict([[key, value]]);
assertEq(items.get(key), value, 'arbitrary object key using hash');
assert(dict([[1, 1]]).hasKey(1), 'hasKey for non-string keys positive');
assert(!dict([[1, 1]]).hasKey('1'), 'hasKey for non-string keys negative');
assertEq(dict([['prototype', 10]]).keys(), ['prototype'], 'keys normally masked by object work');
assertEq(dict([['hasOwnProperty', 10]]).keys(), ['hasOwnProperty'], 'keys normally masked by object work');

assertEq(dict().keys(), [], 'empty dictionary keys equal empty array');
assertEq(dict(), {}, 'empty dictionary equal empty object');
assertEq(dict(), dict(), 'empty dictionary equal empty dictionary');

var a = {'a': 10, 'b': 20};
assertEq(a, a, 'object equals self');
assertEq(a, dict(a), 'object equals dict of self');
assertEq(dict(a), a, 'dict of object equals self');
assertEq(dict(a), dict(a), 'dict of object equals dict of self');
a = dict(a);
assertEq(a, a, 'dict of object equals the same dict of object')

var lettersString = 'abc';
var lettersArray = ['a', 'b', 'c'];
var lettersArrayLength = lettersArray.length;
var numbersArray = [1, 2, 3];
var lettersToNumbers = {'a': 1, 'b': 2, 'c': 3};
var lettersToNumbersItems = [['a', 1], ['b', 2], ['c', 3]];

var D = dict(lettersToNumbers);

assertEq(dict(D), D, 'dict copy');
assertEq(D.copy(), D, 'copy');
assertEq(D.dict(), D, 'dict dict');
assertEq(D.keys(), lettersArray, 'keys');
assertEq(D.keys(), lettersString.split(''), 'keys');
assertEq(D.keysIter().list(), lettersArray, 'keysIter');
assertEq(D.values(), numbersArray, 'values');
assertEq(D.valuesIter().list(), numbersArray, 'valuesIter');
assertEq(D.items(), lettersToNumbersItems, 'items');
assertEq(D.itemsIter().to(array), lettersToNumbersItems, 'itemsIter');
assert(D.has('a'), 'has positive');
assert(!D.has('d'), 'has negative');
assertEq(D.get('a', 2), 1, 'get positive');
assertEq(D.get('d', 4), 4, 'get negative');
assertError(function () {D.get('d')}, KeyError, 'get negative');
D.set('d', 4);
assertEq(D.keys(), ['a', 'b', 'c', 'd'], 'set');
D.del('d');
assertEq(D.keys(), lettersArray, 'del positive');
assertError(function () {D.del('d')}, KeyError, 'del negative');
assert(D.hasValue(2), 'hasValue positive');
assert(!D.hasValue(4), 'hasValue negative');
assert(D.hasKey('a'), 'hasKey positive');
assert(!D.hasKey('d'), 'hasKey negative');
D.update(D);
assertEq(D, lettersToNumbers, 'update with self');
D.update({'c': 1, 'a': 3});
assertEq(D, {'a': 3, 'b': 2, 'c': 1}, 'update with object');
D.update([['a', 1], ['c', 3]]);
assertEq(D, lettersToNumbers, 'update with array of items');
assertEq(D.updated(), D, 'updated');
assertEq(D.updated({'c': 1, 'a': 3}), {'a': 3, 'b': 2, 'c': 1}, 'updated with object');
assertEq(D, lettersToNumbers, 'updated stateless');
assertEq(D.updated([['c', 1]]), {'c': 1, 'b': 2, 'a': 1}, 'updated with items');
assertEq(list(lettersToNumbersItems), lettersToNumbersItems, 'list from array equals original array');
assertEq(dict(lettersToNumbersItems), lettersToNumbers, 'dict from array');
assertNoError(function () {list(lettersToNumbersItems)}, 'list from items no exception');
assertError(function () {list([1, 2, 3]).get('a');}, KeyError, 'string keys throw key error on lists');
assertNoError(function () {
    assertEq(dict(lettersToNumbersItems), dict(list(lettersToNumbersItems)), 'dict equals list of dict');
}, 'dict equals list without exception');
assertEq(dict(list(lettersToNumbersItems)), lettersToNumbers, 'dict from list');
assertEq(dict(zip("abc", "123")), {'a': '1', 'b': '2', 'c': '3'}, 'dict from zip');
assertEq(dict(zip("abc", "123")), {'a': '1', 'b': '2', 'c': '3'}, 'dict from zipIter');

assertEq(D.updated(zipIter(lettersString, count(3, 1))), {'a': 3, 'b': 2, 'c': 1}, 'updated with iteration');
assertEq(dict([['a', 10]]).find(10), 'a', 'find');
assertEq(dict({'a': 10}).object(), {'a': 10}, 'object');

assertEq(hasKey({'a': 10}, 'a'), true, 'hasKey object positive');
assertEq(hasKey({'a': 10}, 'b'), false, 'hasKey object negative');
assertEq(dict([['a', 10], ['b']]), dict([[0, ['a', 10]], [1, ['b']]]), 'construct dict from mixed pairs and 1-tuples');
assertEq(dict(iter([['a', 10], ['b']])), dict([[0, ['a', 10]], [1, ['b']]]), 'construct dict from mixed pairs and 1-tuples in an iteration');

operator.debug = true;
assertEq(get(0)([0]), 0, 'get(0)([0])');
assertEq(len([1,2,3]), 3, 'len([1,2,3])');


/*license

    Legal
    =======
    
    Chiron is a component of the Tale web-game project.
    
    See <credit.txt> for a complete list of
    contributions and their licenses.  All contributions are provided
    under permissive, non-viral licenses including MIT, BSD, Creative Commons
    Attribution 2.5, Public Domain, or Unrestricted.
    
    
    License
    =======
    
    Copyright (c) 2002-2008 Kris Kowal <http://cixar.com/~kris.kowal>
    MIT License
    
    
    MIT License
    -----------
    
    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:
    
    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

